#include "qmission.h"

#include <QUuid>

QMission::QMission(QObject *parent) :
    QObject(parent),
    m_address(-1),
    m_length(0),
    m_period(1000),
    m_level(10),
    m_uuid(QUuid::createUuid().toString()),
    m_mission_type(DT_READ),
    m_mission_status(MS_READY),
    m_last_time(QDateTime()),
    m_max_read(16),
    m_max_write(1)
{
}

QMission::~QMission()
{
    m_address_info.clear();
}

void QMission::set_send_buffer(const QByteArray &data)
{
    m_send_buffer=data;
}

QByteArray QMission::get_send_buffer()
{
    return m_send_buffer;
}

void QMission::set_recv_buffer(const QByteArray &data)
{
    m_recv_buffer=data;
}

QByteArray QMission::get_recv_buffer()
{
    return m_recv_buffer;
}

int QMission::get_address()
{
    return m_address;
}

int QMission::get_length()
{
    return m_length;
}

int QMission::get_level()
{
    return m_level;
}

int QMission::get_machine_address()
{
    return m_machine_address;
}

int QMission::get_period()
{
    return m_period;
}

QString QMission::get_uuid()
{
    return m_uuid;
}

void QMission::set_mission_status(enMissionStatus status)
{
    m_mission_status=status;
}

enMissionStatus QMission::get_mission_status()
{
    return m_mission_status;
}

void QMission::ready()
{
    set_mission_status(MS_READY);
    m_last_time=QDateTime(QDate(2000,1,1),QTime(0,0,0));
}

double QMission::get_todo()
{
    if(m_address<0)
    {
        return 0;
    }

    qint64 dis=m_last_time.msecsTo(QDateTime::currentDateTime());

    if(m_period<=0)
    {
        return dis;
    }
    else
    {
        if(dis>=m_period)
        {
            return (dis-m_period)*0.1/m_period;
        }
    }

    return 0;
}

QString QMission::add_address_inforamtion(tagDriverDataInfo *info)
{
    if(m_address_info.size()>0)
    {
        if(m_mission_type!= info->m_type||
                (m_period<=100 && info->m_period>100) ||
                (m_period>100 && info->m_period<=100) ||
                m_machine_address!=info->m_machine_address)
        {
            return "";
        }

        if(info->m_data_address<=m_address)
        {
            if(info->m_type==DT_READ)
            {
                if(m_address-info->m_data_address+m_length>m_max_read)
                {
                    return "";
                }
            }
            else if(info->m_type==DT_WRITE)
            {
                if(m_address-info->m_data_address+m_length>m_max_write)
                {
                    return "";
                }
            }
            m_address=info->m_data_address;

        }
        else if(info->m_data_address>=m_address+m_length)
        {
            if(info->m_type==DT_READ)
            {
                if(info->m_data_address-m_address>m_max_read)
                {
                    return "";
                }
            }
            else if(info->m_type==DT_WRITE)
            {
                if(info->m_data_address-m_address>m_max_write)
                {
                    return "";
                }
            }
            m_length=info->m_data_address-m_address+1;
        }
    }
    else
    {
        m_machine_address=info->m_machine_address;
        m_address=info->m_data_address;
        m_length=1;
        m_mission_type=info->m_type;
        m_period=info->m_period;
    }
    if(m_level>info->m_level)
    {
        m_level=info->m_level;
    }

    if(m_period<info->m_period)
    {
        m_period=info->m_period;
    }

    m_address_info.insert(info->m_uuid,info);

    return m_uuid;
}

bool QMission::remove_address_information(const QString &uuid)
{
    tagDriverDataInfo *info=m_address_info.value(uuid);

    if(info!=NULL)
    {
        m_address_info.remove(uuid);
        update();
        return true;
    }
    return false;
}

void QMission::update()
{
    if(m_address_info.size()==0)
    {
        return;
    }
    int min,max,level,period;

    tagDriverDataInfo *info=m_address_info.values().first();

    max=min=info->m_data_address;
    level=info->m_level;
    period=info->m_period;

    for(int i=1;i<m_address_info.values().size();i++)
    {
        info=m_address_info.values().at(i);
        if(info->m_data_address<min)
        {
            min=info->m_data_address;
        }

        if(info->m_data_address>max)
        {
            max=info->m_data_address;
        }

        if(info->m_level<level)
        {
            level=info->m_level;
        }

        if(info->m_period<period)
        {
            period=info->m_period;
        }
    }

    m_level=level;
    m_address=min;
    m_length=max-min+1;
    m_period=period;
    ready();
}

enDataTpye QMission::get_mission_type()
{
    return m_mission_type;
}

void QMission::set_max_read(int read)
{
    m_max_read=read;
}

void QMission::set_max_write(int write)
{
    m_max_write=write;
}

QMap<QString,tagDriverDataInfo*> QMission::get_address_info()
{
    return m_address_info;
}

void QMission::set_last_time(QDateTime time)
{
    m_last_time=time;
}
